import { createAction, createReducer, ActionType, createAsyncAction } from 'typesafe-actions';
import { Dispatch } from 'redux';
import Axios from 'axios';
import produce from 'immer';

export interface WordUserRelationTypeSelectIndexDto {
    value: string
    id: number
}
export interface WordUserRelationTypeSelectDto {
    dtos: WordUserRelationTypeSelectIndexDto[]
}

export interface WordUserRelationTypeSelectState {
    dto: WordUserRelationTypeSelectDto;
    currentTypeId: number
    currentTypeValue: string
};

const setState = createAction('WORD_USER_RELATION_TYPE_SELECT/SET_STATE')<WordUserRelationTypeSelectState>();

const fetchActions = createAsyncAction(
    'WORD_USER_RELATION_TYPE_SELECT/FETCH/REQUEST',
    ['WORD_USER_RELATION_TYPE_SELECT/FETCH/SUCCESS', (res: WordUserRelationTypeSelectDto) => res],
    ['WORD_USER_RELATION_TYPE_SELECT/FETCH/FAILURE', (err: Error) => err],
    'WORD_USER_RELATION_TYPE_SELECT/FETCH/CANCEL',
)();
const addActions = createAsyncAction(
    'WORD_USER_RELATION_TYPE_SELECT/ADD/REQUEST',
    ['WORD_USER_RELATION_TYPE_SELECT/ADD/SUCCESS', (res: { id: number, value: string }) => res],
    ['WORD_USER_RELATION_TYPE_SELECT/ADD/FAILURE', (err: Error) => err],
    'WORD_USER_RELATION_TYPE_SELECT/ADD/CANCEL',
)();
const editActions = createAsyncAction(
    'WORD_USER_RELATION_TYPE_SELECT/EDIT/REQUEST',
    ['WORD_USER_RELATION_TYPE_SELECT/EDIT/SUCCESS', (res: { id: number, newValue: string }) => res],
    ['WORD_USER_RELATION_TYPE_SELECT/EDIT/FAILURE', (err: Error) => err],
    'WORD_USER_RELATION_TYPE_SELECT/EDIT/CANCEL',
)();
const removeActions = createAsyncAction(
    'WORD_USER_RELATION_TYPE_SELECT/REMOVE/REQUEST',
    ['WORD_USER_RELATION_TYPE_SELECT/REMOVE/SUCCESS', (res: number) => res],
    ['WORD_USER_RELATION_TYPE_SELECT/REMOVE/FAILURE', (err: Error) => err],
    'WORD_USER_RELATION_TYPE_SELECT/REMOVE/CANCEL',
)();

export const setId = createAction('WORD_USER_RELATION_TYPE_SELECT/SET_ID')<number>();
export const setValue = createAction('WORD_USER_RELATION_TYPE_SELECT/SET_VALUE')<string>();


export type Actions = ActionType<typeof fetchActions>
    | ActionType<typeof setState>
    | ActionType<typeof setId>
    | ActionType<typeof setValue>
    | ActionType<typeof addActions>
    | ActionType<typeof editActions>
    | ActionType<typeof removeActions>
    ;

export const fetch = () =>
    async (dispatch: Dispatch) =>
        Axios.get<WordUserRelationTypeSelectDto>(`wordUserRelationType`)
            .then(res => dispatch(fetchActions.success(res.data)))
            .catch(error => dispatch(fetchActions.failure(error)))

export const add = (value: string) =>
    async (dispatch: Dispatch) =>
        Axios.post<number>(`wordUserRelationType/${value}`)
            .then(res => dispatch(addActions.success({ id: res.data, value })))
            .catch(error => dispatch(addActions.failure(error)))

export const edit = (id: number, newValue: string) =>
    async (dispatch: Dispatch) =>
        Axios.put(`wordUserRelationType/${id}/${newValue}`)
            .then(_ => dispatch(editActions.success({ id, newValue })))
            .catch(error => dispatch(editActions.failure(error)))

export const remove = (id: number) =>
    async (dispatch: Dispatch) =>
        Axios.delete<WordUserRelationTypeSelectDto>(`wordUserRelationType/${id}`)
            .then(res => dispatch(removeActions.success(id)))
            .catch(error => dispatch(removeActions.failure(error)))

const initialState: WordUserRelationTypeSelectState = {
    currentTypeId: 1,
    currentTypeValue: '默认关联',
    dto: { dtos: [] }
};

export const Reducer = createReducer<WordUserRelationTypeSelectState, Actions>(initialState)
    .handleAction(setState, (_, action) => action.payload)
    .handleAction(fetchActions.success, (state, action) => produce(state, draft => {
        draft.dto = action.payload
        if (action.payload.dtos.length !== 0)
            draft.currentTypeId = action.payload.dtos[0].id
    })
    )
    .handleAction(setId, (state, action) => produce(state, draft => {
        draft.currentTypeId = action.payload
    }))
    .handleAction(setValue, (state, action) => produce(state, draft => {
        draft.currentTypeValue = action.payload
    }))
    .handleAction(addActions.success, (state, action) => produce(state, draft => {
        console.log(state);
        draft.dto.dtos.push({ id: action.payload.id, value: action.payload.value })
    }))
    .handleAction(editActions.success, (state, action) => produce(state, draft => {
        const i = draft.dto.dtos.findIndex(e => e.id === action.payload.id)
        draft.dto.dtos[i].value = action.payload.newValue
    }))
    .handleAction(removeActions.success, (state, action) => produce(state, draft => {
        draft.dto.dtos = draft.dto.dtos.filter(e => e.id !== action.payload)
    }))

